/**
 * 
 */
package handwritten.grid;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.geom.Line2D;
import java.util.ArrayList;

import utility.math.Vector2D;

/**
 * @author tioz
 *
 */
public class SingleCellTrainning extends InputGrid implements Trainning{

	Font font;
	
	ArrayList<String> listToLearn;
	
	private int currentChar = 10;
	
	final static BasicStroke dashed =
	        new BasicStroke(1.0f,
	                        BasicStroke.CAP_BUTT,
	                        BasicStroke.JOIN_MITER,
	                        10.0f, new float[]{2}, 0.0f);
	final static BasicStroke nodashed =
	        new BasicStroke(1.0f);

	int lineWidth = 2;
	
	int startX,startY,endX,endY;
	
	//Total width and eight (cell + linee)
	int cellWidth;
	int cellHeight;
	//number of cell along x
	int numberOfCellX;
	//center the cell with an offset
	int offsetX;
	
	//number of cell along y
	int numberOfCellY;
	//center the cell with an offset
	int offsetY;
	
	int beginOfgridX;
	int endOfgridX;
	
	int beginOfgridY;
	int endOfgridY;
	
	/**
	 * @param lineWidth
	 * @param textCellWidth
	 * @param textCellHeight
	 * @param textUnderlineHeight
	 */
	public SingleCellTrainning(int textCellWidth,
			int textCellHeight, int textUnderlineHeight) {
		super(textCellWidth, textCellHeight, textUnderlineHeight);
		
		font       = new Font(getSystemFontList()[0],Font.PLAIN, 16);
		listToLearn= new ArrayList<String>();
	
		for (int c = 0x28; c <= 0x7E; c++)
		{	
		  if (font.canDisplay((char)c))
		  {
			listToLearn.add(Character.toString((char)c));
		  }
		}
		
		currentChar = (int)(Math.random()*(listToLearn.size()-1));
		
		startX			=0;
		startY			=0;
		endX			=0;
		endY			=0;
		cellWidth		=0;
		cellHeight		=0;
		numberOfCellX	=0;
		offsetX			=0;
		numberOfCellY	=0;
		offsetY			=0;
		beginOfgridX	=0;
		endOfgridX		=0;
		beginOfgridY	=0;
		endOfgridY		=0;
	}
	
	public static String[] getSystemFontList()
	{
	    return GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
	
	}

	public static void terminalPrintFontList()
	{
	    String fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
	    
	    for( int i = 0; i < fonts.length; i++ )
	    {
	      System.out.println(fonts[i]);
	    }	
	}
	
	
	public void paint(Graphics2D g){
		g.setFont(font);
		g.setColor(new Color(200,0,60));
		
		g.setStroke(new BasicStroke(lineWidth));
		g.setColor(new Color(0,0,0));
		//there is numberOfcell +1 lines
		for(int i=0; i<= 1;i++){ 
			
			int xHeight= beginOfgridX + i*cellWidth;
											
			Line2D.Float line = new Line2D.Float(xHeight,beginOfgridY,xHeight,endOfgridY);
	    	g.draw(line);
    	}
		for(int i=0; i<= 1;i++){ 
							
			int yWidth= beginOfgridY + i*cellHeight;
			
			Line2D.Float line1 = new Line2D.Float(beginOfgridX,yWidth,endOfgridX,yWidth);
			g.draw(line1);
			if(i!=0)
			{
				Line2D.Float line2 = new Line2D.Float(beginOfgridX,yWidth-textUnderlineHeight,endOfgridX,yWidth-textUnderlineHeight);
				g.setStroke(dashed);
				g.draw(line2);
			}
			g.setStroke(nodashed);
    	}
		Vector2D[] pos = getCellBoundary(0, 0);
		g.drawString(String.valueOf(expectedChar(new int[]{0,0})),(int)pos[0].getX()+3,(int)pos[0].getY()+font.getSize());
	
	}
	
	


	/* (non-Javadoc)
	 * @see textRecognition.grid.Trainning#expectedChar(int, int)
	 */
	@Override
	public String expectedChar(int[] n) {
		return listToLearn.get(currentChar);
	}

	/* (non-Javadoc)
	 * @see textRecognition.grid.InputGrid#update(int, int, int, int)
	 */
	@Override
	public void update(int startX, int startY, int endX, int endY) {
		this.startX = startX;
		this.startY = startY;
		this.endX = endX;
		this.endY = endY;
		
		//Total width and eight (cell + line== 1/2 line on each side)
		cellWidth = textCellWidth  +lineWidth;
		cellHeight= textCellHeight +lineWidth;
		//number of cell along x (we have an extra line to draw)
		numberOfCellX = 1;
		//center the cell with an offset
		offsetX       =(((endX-startX)-cellWidth)+lineWidth)/2;
		
		//number of cell along y
		numberOfCellY =1;
		//center the cell with an offset
		offsetY       =(((endY-startY)-cellHeight)+lineWidth)/2;
		
    	beginOfgridX = startX+offsetX;
    	endOfgridX   = startX+offsetX + numberOfCellX*cellWidth ;
    	
    	beginOfgridY = startY+offsetY;
    	endOfgridY   = startY+offsetY + numberOfCellY*cellHeight ;
		
	}



	public Vector2D[] getCellBoundary(Vector2D pos)
	{
		int nX  = (int)(pos.getX()-beginOfgridX)/(textCellWidth + lineWidth);
		int nY  = (int)(pos.getY()-beginOfgridY)/(textCellHeight + lineWidth);
		
		//System.out.println(nX+" and "+nY);
		
		return getCellBoundary(nX,nY);
	}
	
	/**
	 * retourn the real boundary of the {(nx+1),(ny+1)} Cell(not the line)
	 * @param nX
	 * @param nY
	 * @return
	 */
	public Vector2D[] getCellBoundary(int nX,int nY)
	{
		Vector2D top = new Vector2D(beginOfgridX+nX*cellWidth+lineWidth/2
				   				   ,beginOfgridY+nY*cellHeight+lineWidth/2);
		
		Vector2D bottom= new Vector2D( top.getX()+textCellWidth, top.getY()+textCellHeight);
		
		Vector2D tmp[]={top,bottom};
		
		return tmp;
	}

	/* (non-Javadoc)
	 * @see textRecognition.grid.InputGrid#getCellNumber(utility.math.Vector2D)
	 */
	@Override
	public int[] getCellNumber(Vector2D pos) {
		int nX  = (int)(pos.getX()-beginOfgridX)/(textCellWidth + lineWidth);
		int nY  = (int)(pos.getY()-beginOfgridY)/(textCellHeight + lineWidth);
		
		//System.out.println(nX+" and "+nY);
		int tmp[]={nX,nY};
		
		return tmp;
	}

	/* (non-Javadoc)
	 * @see textRecognition.grid.Trainning#setExpectedChar(int)
	 */
	@Override
	public void setExpectedChar(int[] n) {
		currentChar = n[0];
	}

	/* (non-Javadoc)
	 * @see textRecognition.grid.Trainning#charCollectionSize()
	 */
	@Override
	public int charCollectionSize() {
		return listToLearn.size();
	}

	/* (non-Javadoc)
	 * @see handwritten.grid.InputGrid#getCellTopLeft(int, int)
	 */
	@Override
	public Vector2D getCellTopLeft(Vector2D pos) {
		int nX  = (int)(pos.getX()-beginOfgridX)/(textCellWidth + lineWidth);
		int nY  = (int)(pos.getY()-beginOfgridY)/(textCellHeight + lineWidth);
		return new Vector2D(beginOfgridX+nX*cellWidth+lineWidth/2
				   ,beginOfgridY+nY*cellHeight+lineWidth/2);
	}
	
 
	
}
